/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "光栅渲染.h"

#include "节点/插座/材质纹理插座.h"

#include "节点/插座/C_矢量插座.h"
#include "节点/插座/list/list物体插座.h"
#include "节点/插座/list/list数值插座.h"

#include <物体/S_摄像机.h>

#include "异步解算/物理异步解算.h"



C_光栅阴影渲染节点::C_光栅阴影渲染节点(S_设备环境& ctx) : C_节点基类(DEF_光栅阴影渲染节点, E_节点类型::e_节点Type_渲染) {
	m_Ctx = ctx;
	f_setWName(u"阴影渲染");

	f_nodePlugin_创建插座(this, E_插座方向::e_插座Type_输入, {
		{E_值类型::e_Type_Object_1D, u"物体", false},
		{E_值类型::e_Type_Object_1D, u"灯光", false},
	});

	f_nodePlugin_创建插座(this, E_插座方向::e_插座Type_输出, {
		{E_值类型::e_Type_Object_1D, u"灯光", false},
	});


	m_摄像机GPU参数槽 = {};
	f_df_allocGPU参数缓存槽(&m_摄像机GPU参数槽, 1);
	//m_摄像机GPU参数槽.m_GPU布局描述 = S_Engine::g_摄像机GPU布局描述;

	m_自定义更新方式 = true;
}

C_光栅阴影渲染节点::~C_光栅阴影渲染节点() {
	
}

bool C_光栅阴影渲染节点::f_update() {
	
	auto light = DEF_物体插座_1D数据(f_get输入插座(2));

	f_get输出插座(1)->f_setData(light);

	//f_NodeCtx_节点模拟入栈(this, false);
	f_异步解算();

	return false;
}

void C_光栅阴影渲染节点::f_异步解算() {
	auto ob = DEF_物体插座_1D数据(f_get输入插座(1));
	auto light = DEF_物体插座_1D数据(f_get输入插座(2));


	S_Viewport view = { 0, 0, 0, 0, 0.0f, 1.0f };
	S_Rect2D 裁剪 = { _iVec2(0), _uVec2(0) };

	S_渲染参数 渲染参数{};
	渲染参数.m_线管槽 = E_管线槽::e_阴影渲染;





	for (uint32 i = 0; i < light->count; ++i) {
		auto 灯光对象 = f_ob_get子对象(light->ptr_userData[i], 0);
		auto* lp = f_ob_getLigth(灯光对象);


		Mat44f mat[4];
		auto obMat = f_ob_get变换矩阵(灯光对象, 0);
		mat[1] = f_mat44_Invert(obMat);
		mat[3] = mat[1];

		f_bm_resize(lp->m_灯光阴影矩阵, lp->m_阴影图->count);
		auto* projMatrix = f_bm_ptr<Mat44f>(lp->m_灯光阴影矩阵);

		for (uint32 光采样ID = 0; 光采样ID < lp->m_阴影图->count; ++光采样ID) {
			auto arce = lp->m_帧缓存->ptr_userData[光采样ID]->m_Size;

			view.width = arce.x;
			view.height = arce.y;
			裁剪.extent = arce;


			switch (lp->m_灯光类型) {
				case E_物体类型::t_区域光: {
					auto 区域光 = f_bm_ptr<S_LightArea>(lp->m_灯光数据);

					switch (区域光->m_samplerType_samplerNum >> 16) {
						case E_投影模式::e_透视: {
							break;
						}
						case E_投影模式::e_正交: {
							break;
						}
					}
					break;
				}
			}

			static int32 转 = 0;

			//auto 渲染参数 = f_scene_开始渲染(m_Scene, m_镜头, 视口大小, 视口偏移);
			Mat44f proj = f_light_计算区域光视口(lp, 光采样ID, obMat);
			//Mat44f proj = f_light_计算区域光视口(lp, _Vec2(float32(++转) * 0.1), obMat);
			mat[0] = proj * mat[1];
			mat[2] = proj;
			projMatrix[光采样ID] = mat[0];

			f_buf_fill(S_节点数据::g_节点渲染摄像机矩阵, mat, 4);


			m_摄像机GPU参数槽.m_参数槽[0] = S_节点数据::g_节点渲染摄像机矩阵;
			m_摄像机GPU参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
			m_摄像机GPU参数槽.m_绑定位置[0] = 0;
			m_摄像机GPU参数槽.m_绑定数量[0] = 1;
			f_df_setGPU参数布局(m_Ctx.m_逻辑设备.设备, m_摄像机GPU参数槽);


			渲染参数.m_视图投影矩阵 = S_节点数据::g_节点渲染摄像机矩阵;
			渲染参数.m_视口 = &view;
			渲染参数.m_裁剪 = &裁剪;


			f_df_BeginDraw(&m_Ctx, lp->m_帧缓存->ptr_userData[光采样ID], 光采样ID, 1);

			for (uint32 k = 0; k < ob->count; ++k) {
				auto e = ob->ptr_userData[k];

				switch (e->m_Type) {
					case E_物体类型::t_物体包:
					case E_物体类型::t_多边形:
					case E_物体类型::t_网格物体: {
						if (!e->m_父对象) f_ob_绘制单个元素(e, 渲染参数, E_物体网格元素类型::e_MT_纹理);
					}
				}
			}

			f_Draw_end_帧缓存(m_Ctx);
		}

	}
}

void C_光栅阴影渲染节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_5, S_引擎配置::g_文件版本号)) {
			//下一次读取数据指针 = f_prop_Load(m_形状类型, 下一次读取数据指针);
			//下一次读取数据指针 = f_ob_Load物体(m_Ob, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_光栅阴影渲染节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	//f_prop_Save(m_形状类型, 块);
	//f_ob_Save物体(m_Ob, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建光栅阴影渲染节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_光栅阴影渲染节点(ctx);
}

C_节点基类* f_node_加载光栅阴影渲染节点(S_设备环境& ctx, FILE* f) {
	C_光栅阴影渲染节点* node = new C_光栅阴影渲染节点(ctx);
	return node;
}

void f_node_保存光栅阴影渲染节点(C_节点基类* n, FILE* f) {
	C_光栅阴影渲染节点* node = dynamic_cast<C_光栅阴影渲染节点*>(n);
}



/*












*/

//uint32 f_分辨率;

C_环境渲染节点::C_环境渲染节点(S_设备环境& ctx) : C_节点基类(DEF_光栅环境渲染节点, E_节点类型::e_节点Type_渲染) {
	m_Ctx = ctx;
	f_setWName(u"环境渲染");

	f_nodePlugin_创建插座(this, E_插座方向::e_插座Type_输入, {
		{E_值类型::e_Type_Object_1D, u"物体", false},
		{E_值类型::e_Type_Object_1D, u"灯光", false},
		{E_值类型::e_Type_Vec3, u"中心", false},
	});

	f_nodePlugin_创建插座(this, E_插座方向::e_插座Type_输出, {
		{E_值类型::e_Type_纹理_1D, u"环境", false},
	});


	uint32 分辨率 = 1024;
	m_环境渲染层 = f_surface_CreateCube(ctx, { 分辨率,分辨率 }, { 分辨率,分辨率 }, S_节点数据::g_场景渲染纹理采样器, 3);
	f_tex_立方体纹理深度布局(m_环境渲染层->m_Depth[0], 6);


	m_渲染纹理 = f_alloc_Prop纹理集(nullptr, u"渲染贴图");
	m_渲染纹理.m_私有 = true;

	m_渲染分辨率 = f_alloc_EnumProp(nullptr, { 
		{u"32"},{u"64"},{u"128"},{u"256"},{u"512"},
		{u"1024"},{u"2048"},{u"4096"},{u"8192"} },
	u"分辨率", 5);
	m_渲染分辨率.m_私有 = true;

	m_模糊 = f_alloc_F32Prop(nullptr, u"模糊", 1);
	m_模糊.m_私有 = true;

	m_模糊采样 = f_alloc_F32Prop(nullptr, u"模糊采样", 1);
	m_模糊采样.m_私有 = true;


	m_摄像机GPU参数槽 = {};
	f_df_allocGPU参数缓存槽(&m_摄像机GPU参数槽, 1);
	//m_摄像机GPU参数槽.m_GPU布局描述 = S_Engine::g_摄像机GPU布局描述;


	m_环境参数布局槽 = f_engine_环境渲染参数槽布局2();
	m_环境后期布局槽 = f_engine_环境后期参数槽布局0();

	
	m_环境纹理集 = f_纹理集_创建();
	f_纹理集_add纹理(m_环境纹理集, m_环境渲染层->m_Color[0]);
	//f_纹理集_add纹理(m_环境纹理集, m_环境渲染层->m_Color[1]);
	//f_纹理集_add纹理(m_环境纹理集, m_环境渲染层->m_Color[2]);
	m_纹理槽 = f_纹理槽_创建(1);
	f_纹理槽_设置纹理集(m_纹理槽, m_环境纹理集, 0, DEF_BindID_CompositingShadow);


	auto& ts = f_prop_纹理集(m_渲染纹理);
	f_纹理集_set数量(ts.m_纹理集, 1);
	f_纹理集_set纹理(ts.m_纹理集, m_环境渲染层->m_Color[1], 0);

	m_自定义更新方式 = true;
}

C_环境渲染节点::~C_环境渲染节点() {
	f_df_freeGPU参数缓存槽(&m_摄像机GPU参数槽);
	f_df_freeGPU参数缓存槽(&m_环境参数布局槽);

	f_surface_Release(m_环境渲染层);

	f_prop_Release(m_渲染分辨率);
	f_prop_Release(m_模糊);
	f_prop_Release(m_模糊采样);
}

bool C_环境渲染节点::f_update() {
	int32 分辨率 = f_prop_enum(m_渲染分辨率);
	//分辨率 = 32 * (分辨率+1);
	分辨率 = exp2(分辨率+5);

	uint32 图像分块 = (分辨率 / 32);
	分辨率 = 图像分块 * 32;

	
	f_surface_Cube改变大小(m_环境渲染层, _uVec2(分辨率));
	

	//f_纹理集_刷新所有纹理信息(m_环境纹理集);
	//f_纹理槽_设置纹理集(m_纹理槽, m_环境纹理集, 0, DEF_BindID_TextureCube);

	auto tex = DEF_纹理插座_1D数据(f_get输出插座(1));
	f_core_array_resize((S_Array*)tex, 3);
	
	m_全局常量属性 = {};
	m_全局常量属性.m_blur = f_prop_F32(m_模糊);
	m_全局常量属性.m_blurSample = f_prop_F32(m_模糊采样);

	f_异步解算();

	tex->ptr_userData[0] = m_环境渲染层->m_Color[0];
	tex->ptr_userData[1] = m_环境渲染层->m_Color[1];
	tex->ptr_userData[2] = m_环境渲染层->m_Color[2];


	auto& ts = f_prop_纹理集(m_渲染纹理);
	f_纹理集_set纹理(ts.m_纹理集, m_环境渲染层->m_Color[0], 0);


	//f_NodeCtx_节点模拟入栈(this, false);
	return false;
}

void C_环境渲染节点::f_异步解算() {
	auto* 渲染物体 = DEF_物体插座_1D数据(f_get输入插座(1));
	auto* 灯光物体 = DEF_物体插座_1D数据(f_get输入插座(2));
	auto 中心 = DEF_Vec3插座数据(f_get输入插座(3));

	S_渲染参数 渲染参数{};
	渲染参数.m_线管槽 = E_管线槽::e_环境渲染;



	S_Viewport view = { 0, 0, 0, 0, 0.0f, 1.0f };
	S_Rect2D 裁剪 = { _iVec2(0), _uVec2(0) };

	Mat44f mat[6];
	f_math_Cube相机矩阵(中心, mat);
	auto 相机投影矩阵 = f_mat4_ProjectionMatrix(90, 1, 0.01, 10000);

	uint32 分辨率 = f_prop_enum(m_渲染分辨率);
	分辨率 = exp2(分辨率 + 5);

	uint32 图像分块 = (分辨率 / 32);
	分辨率 = 图像分块 * 32;


	Mat44f 相机矩阵[4];
	

	m_环境参数布局槽.m_参数槽[0] = f_buf_getGlobal().g_材质;
	m_环境参数布局槽.m_参数类型[0] = E_板载缓存类型::e_SSBO;
	m_环境参数布局槽.m_绑定位置[0] = DEF_BINDING_TasterBindID_MaterialID;
	m_环境参数布局槽.m_绑定数量[0] = 1;

	
	for (uint32 i = 0; i < 6; ++i) {
		
		相机矩阵[0] = (*(Mat44f*)&相机投影矩阵) * mat[i];
		相机矩阵[1] = mat[i];
		相机矩阵[2] = (*(Mat44f*)&相机投影矩阵);
		相机矩阵[3] = mat[i];
		f_buf_fill(S_节点数据::g_节点渲染摄像机矩阵, 相机矩阵, 4);

		m_摄像机GPU参数槽.m_参数槽[0] = S_节点数据::g_节点渲染摄像机矩阵;
		m_摄像机GPU参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
		m_摄像机GPU参数槽.m_绑定位置[0] = 0;
		m_摄像机GPU参数槽.m_绑定数量[0] = 1;
		f_df_setGPU参数布局(m_Ctx.m_逻辑设备.设备, m_摄像机GPU参数槽);


		view.width = 分辨率;
		view.height = 分辨率;
		裁剪.extent = { 分辨率, 分辨率 };

		渲染参数.m_视图投影矩阵 = S_节点数据::g_节点渲染摄像机矩阵;
		渲染参数.m_视口 = &view;
		渲染参数.m_裁剪 = &裁剪;

		switch (i) {
			case 0: m_环境渲染层->m_帧缓存->m_清除颜色 = vec4{ 1,    0,    0,    1 }; break;
			case 1: m_环境渲染层->m_帧缓存->m_清除颜色 = vec4{ 0.25, 0,    0,    1 }; break;
			case 2: m_环境渲染层->m_帧缓存->m_清除颜色 = vec4{ 0,    1,    0,    1 }; break;
			case 3: m_环境渲染层->m_帧缓存->m_清除颜色 = vec4{ 0,    0.25, 0,    1 }; break;
			case 4: m_环境渲染层->m_帧缓存->m_清除颜色 = vec4{ 0,    0,    1,    1 }; break;
			case 5: m_环境渲染层->m_帧缓存->m_清除颜色 = vec4{ 0,    0,    0.25, 1 }; break;
			default:
				m_环境渲染层->m_帧缓存->m_清除颜色 = vec4{ 1, 1, 1, 1 };
				break;
		}

		
		
		f_df_BeginDraw(&m_Ctx, m_环境渲染层->m_帧缓存, i, 2);

		f_df_setGPU参数布局(m_Ctx.m_逻辑设备.设备, m_环境参数布局槽, false);

		for (uint32 i = 0; i < 渲染物体->count; ++i) {
			auto e = 渲染物体->ptr_userData[i];

			switch (e->m_Type) {
				case E_物体类型::t_物体包:
				case E_物体类型::t_多边形:
				case E_物体类型::t_网格物体: {
					if (!e->m_父对象) f_ob_绘制单个元素(e, 渲染参数, E_物体网格元素类型::e_MT_纹理);
					break;
				}
			}
		}

		for (uint32 i = 0; i < 灯光物体->count; ++i) {
			auto e = 灯光物体->ptr_userData[i];

			switch (e->m_Type) {
				case E_物体类型::t_灯光:
				case E_物体类型::t_区域光: {
					if (!e->m_父对象) f_ob_绘制单个元素(e, 渲染参数, 0);
					break;
				}
			}
		}
		f_Draw_end_帧缓存(m_Ctx);
	}


	f_纹理集_set纹理(m_环境纹理集, m_环境渲染层->m_Color[0], 0);

	m_全局常量属性.m_resolutionRatio = { 分辨率, 分辨率 };
	

	f_纹理集_刷新所有纹理信息(m_环境纹理集);
	f_纹理槽_设置纹理集(m_纹理槽, m_环境纹理集, 0, 0);
	
	m_环境后期布局槽.m_参数槽[0] = m_环境渲染层->m_Color[1];
	m_环境后期布局槽.m_参数类型[0] = E_板载缓存类型::e_IMAGE;
	m_环境后期布局槽.m_绑定位置[0] = 1;
	m_环境后期布局槽.m_绑定数量[0] = 1;

	m_环境后期布局槽.m_参数槽[1] = m_环境渲染层->m_Color[2];
	m_环境后期布局槽.m_参数类型[1] = E_板载缓存类型::e_IMAGE;
	m_环境后期布局槽.m_绑定位置[1] = 2;
	m_环境后期布局槽.m_绑定数量[1] = 1;

	m_环境后期布局槽.m_纹理槽 = &m_纹理槽;
	
	f_df_run计算(S_Engine::g_后期处理.g_光栅环境后期, { 图像分块 / 2, 图像分块 / 2, 1 }, m_环境后期布局槽, &m_全局常量属性);

}

void C_环境渲染节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		//下一次读取数据指针 = f_prop_Load(m_渲染纹理, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_渲染分辨率, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_模糊, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_模糊采样, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_环境渲染节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_渲染分辨率, 块);
	f_prop_Save(m_模糊, 块);
	f_prop_Save(m_模糊采样, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建环境渲染节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_环境渲染节点(ctx);
}

C_节点基类* f_node_加载环境渲染节点(S_设备环境& ctx, FILE* f) {
	C_环境渲染节点* node = new C_环境渲染节点(ctx);
	return node;
}

void f_node_保存环境渲染节点(C_节点基类* n, FILE* f) {
	C_环境渲染节点* node = dynamic_cast<C_环境渲染节点*>(n);
}





/*

















*/




C_光栅渲染节点::C_光栅渲染节点(S_设备环境& ctx) : C_节点基类(DEF_光栅渲染节点, E_节点类型::e_节点Type_渲染) {
	m_Ctx = ctx;
	f_setWName(u"光栅渲染");

	f_nodePlugin_创建插座(this, E_插座方向::e_插座Type_输入, {
		{E_值类型::e_Type_Object_1D, u"物体", false},
		{E_值类型::e_Type_Object_1D, u"灯光", false},
		{E_值类型::e_Type_纹理_1D, u"环境", false},
		{E_值类型::e_Type_Object, u"摄像机", false},
	});


	m_渲染纹理 = f_alloc_Prop纹理集(nullptr, u"阴影贴图");
	m_渲染纹理.m_私有 = true;

	m_渲染分辨率 = f_alloc_uVec2Prop(nullptr, u"分辨率", {1280, 720});
	m_渲染分辨率.m_私有 = true;

	m_AO深度偏移 = f_alloc_F32Prop(nullptr, u"AO深度偏移", 0.00001);
	m_AO深度偏移.m_私有 = true;

	m_AO半径 = f_alloc_F32Prop(nullptr, u"AO半径", 1);
	m_AO半径.m_私有 = true;

	m_AO强度 = f_alloc_F32Prop(nullptr, u"AO强度", 1.0);
	m_AO强度.m_私有 = true;

	m_AO厚度 = f_alloc_F32Prop(nullptr, u"AO厚度", 1.0);
	m_AO厚度.m_私有 = true;

	m_AO采样 = f_alloc_UI32Prop(nullptr, u"AO采样", 10);
	m_AO采样.m_私有 = true;



	m_阴影强度 = f_alloc_F32Prop(nullptr, u"阴影强度", 1);
	m_阴影强度.m_私有 = true;

	m_阴影采样 = f_alloc_UI32Prop(nullptr, u"阴影采样", 4);
	m_阴影采样.m_私有 = true;

	m_环境亮度 = f_alloc_F32Prop(nullptr, u"环境亮度", 1);
	m_环境亮度.m_私有 = true;




	m_几何缓存渲染层 = f_surface_Create几何缓存(ctx, { 512,512 });
	m_颜色渲染层 = f_surface3D_创建(ctx, {512,512}, ctx.m_采样数);

	m_灯光属性ID = f_bm_alloc(f_buf_getGlobal().m_灯光索引, 0);
	//m_区域光属性 = f_bm_alloc(f_buf_getGlobal().m_区域光缓冲区, 1);
	//m_区域光投影矩阵 = f_bm_alloc(f_buf_getGlobal().g_灯光投影矩阵, 1);


	m_摄像机GPU参数槽 = {};
	f_df_allocGPU参数缓存槽(&m_摄像机GPU参数槽, 1);
	//m_摄像机GPU参数槽.m_GPU布局描述 = S_Engine::g_摄像机GPU布局描述;


	m_屏幕后期合成纹理 = f_tex_创建帧缓存纹理(ctx, { 512, 512, 1 }, E_纹理格式::e_tf_RGBA8U_归一化, E_纹理维度类型::e_2D);
	f_tex_安装纹理采样器(m_屏幕后期合成纹理, S_全局缓存::g_默认采样器);


	m_立方体阴影纹理集 = f_纹理集_创建();
	f_纹理集_add纹理(m_立方体阴影纹理集, f_g_纹理().g_缺损立方体阴影纹理);

	m_深度阴影纹理集 = f_纹理集_创建();
	f_纹理集_add纹理(m_深度阴影纹理集, f_g_纹理().g_缺损阴影纹理);

	m_屏幕后期阴影纹理集 = f_纹理集_创建();
	f_纹理集_add纹理(m_屏幕后期阴影纹理集, m_屏幕后期合成纹理);
	

	m_屏幕后期几何纹理集 = f_纹理集_创建();
	f_纹理集_add纹理(m_屏幕后期几何纹理集, m_几何缓存渲染层->m_Color[0]);
	f_纹理集_add纹理(m_屏幕后期几何纹理集, m_几何缓存渲染层->m_Color[1]);

	


	m_环境纹理集 = f_纹理集_创建();
	f_纹理集_add纹理(m_环境纹理集, S_节点数据::g_缺损环境颜色纹理);
	f_纹理集_add纹理(m_环境纹理集, S_节点数据::g_缺损环境颜色纹理);
	f_纹理集_add纹理(m_环境纹理集, S_节点数据::g_缺损环境颜色纹理);

	




	//几何预渲染
	{
		m_几何纹理槽 = f_纹理槽_创建(3);

		f_纹理槽_设置纹理集(m_几何纹理槽, m_环境纹理集, 0, DEF_BindID_TextureCube);
		f_纹理槽_设置纹理集(m_几何纹理槽, m_深度阴影纹理集, 1, DEF_BindID_TextureShadow);
		f_纹理槽_设置纹理集(m_几何纹理槽, m_立方体阴影纹理集, 2, DEF_BindID_TexCubeShadow);

		m_几何渲染参数槽 = {};
		f_df_allocGPU参数缓存槽(&m_几何渲染参数槽, 4);
		m_几何渲染参数槽.m_GPU布局描述 = S_Engine::g_场景几何纹理渲染布局;
	}



	//后期处理
	{
		m_屏幕后期效果纹理槽 = f_纹理槽_创建(3);

		f_纹理槽_设置纹理集(m_屏幕后期效果纹理槽, m_屏幕后期几何纹理集, 0, DEF_BindID_GBufferImage);
		f_纹理槽_设置纹理集(m_屏幕后期效果纹理槽, m_深度阴影纹理集, 1, DEF_BindID_TextureShadow);
		f_纹理槽_设置纹理集(m_屏幕后期效果纹理槽, m_屏幕后期阴影纹理集, 2, DEF_BindID_CompositingShadow);


		m_后期屏幕效果合成参数槽 = {};
		f_df_allocGPU参数缓存槽(&m_后期屏幕效果合成参数槽, 3);
		m_后期屏幕效果合成参数槽.m_GPU布局描述 = S_Engine::g_后期处理.g_光栅阴影计算->m_参数布局;
	}
	

	
	//最终渲染
	{
		m_最终渲染纹理槽 = f_纹理槽_创建(5);

		f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_环境纹理集, 0, DEF_BindID_TextureCube);
		f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_深度阴影纹理集, 1, DEF_BindID_TextureShadow);
		f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_立方体阴影纹理集, 2, DEF_BindID_TexCubeShadow);
		f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_屏幕后期阴影纹理集, 3, DEF_BindID_CompositingShadow);
		f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_屏幕后期几何纹理集, 4, DEF_BindID_GBufferImage);

		m_最终渲染参数槽 = {};
		f_df_allocGPU参数缓存槽(&m_最终渲染参数槽, 5);
		m_最终渲染参数槽.m_GPU布局描述 = S_Engine::g_光栅最终渲染参数布局;
	}

	

	auto& ts = f_prop_纹理集(m_渲染纹理);
	f_纹理集_add纹理(ts.m_纹理集, m_颜色渲染层->m_Color[0]);
}

C_光栅渲染节点::~C_光栅渲染节点() {
	f_prop_Release(m_渲染纹理);
	f_prop_Release(m_渲染分辨率);

	f_prop_Release(m_AO深度偏移);
	f_prop_Release(m_AO半径);
	f_prop_Release(m_AO强度);
	f_prop_Release(m_AO厚度);
	f_prop_Release(m_AO采样);

	f_prop_Release(m_阴影强度);
	f_prop_Release(m_阴影采样);
	f_prop_Release(m_环境亮度);



	f_df_freeGPU参数缓存槽(&m_摄像机GPU参数槽);
	f_df_freeGPU参数缓存槽(&m_最终渲染参数槽);


	f_纹理集_销毁(m_立方体阴影纹理集);

	f_纹理集_销毁(m_环境纹理集);
	f_纹理集_销毁(m_深度阴影纹理集);
	
	//f_纹理集_销毁(m_G缓存纹理集);

	f_纹理槽_销毁(m_最终渲染纹理槽);

	f_surface_Release(m_颜色渲染层);
}

bool C_光栅渲染节点::f_update() {
	
	auto* 灯光物体 = DEF_物体插座_1D数据(f_get输入插座(2));
	auto* 环境纹理 = DEF_纹理插座_1D数据(f_get输入插座(3));

	auto 分辨率 = f_prop_uVec2(m_渲染分辨率);
	auto 图像分块 = (分辨率 / 32) + 1;
	分辨率 = 图像分块 * 32;


	f_surface_3D改变大小(m_颜色渲染层, 分辨率);
	f_surface_set几何缓存分辨率(m_几何缓存渲染层, 分辨率);
	f_tex_setSize(m_屏幕后期合成纹理, 分辨率);
	//f_surface_setG缓存纹理大小(m_颜色渲染层, 分辨率);
	//auto* 阴影纹理 = DEF_纹理插座_1D数据(f_get输出插座(1));
	//f_core_array_resize((S_Array*)texs, 0);
	f_bm_resize(m_灯光属性ID, 灯光物体->count);
	

	m_全局纹理属性.light_Offset = m_灯光属性ID.m_Mem.m_偏移;
	m_全局纹理属性.light_Num = m_灯光属性ID.m_Mem.m_数量;
	m_全局纹理属性.m_resolutionRatio = 分辨率;

	m_全局纹理属性.m_radiusAO = f_prop_F32(m_AO半径);
	m_全局纹理属性.m_intensityAO = f_prop_F32(m_AO强度);
	m_全局纹理属性.m_thicknessAO = f_prop_F32(m_AO厚度);
	m_全局纹理属性.m_depthBias = f_prop_F32(m_AO深度偏移);
	m_全局纹理属性.m_AO_X_Sample = 8;
	m_全局纹理属性.m_AO_Y_Sample = f_prop_UI32(m_AO采样);

	m_全局纹理属性.m_shadowIntensity = f_prop_F32(m_阴影强度);
	m_全局纹理属性.m_shadowSampleNum = f_prop_UI32(m_阴影采样);

	m_全局纹理属性.m_envIntensity = f_prop_F32(m_环境亮度);




	if (灯光物体->count) {
		std::vector<S_纹理*> 阴影纹理;
		auto 灯光索引 = f_bm_ptr<S_LightIndex>(m_灯光属性ID);


		for (uint32 i = 0; i < 灯光物体->count; ++i) {
			auto light = f_ob_get子对象(灯光物体->ptr_userData[i], 0);
			auto* lp = f_ob_getLigth(light);


			灯光索引[i].m_lightType = lp->m_灯光类型;
			灯光索引[i].m_attIndex = lp->m_灯光数据.m_Mem.m_偏移;

			auto l = f_bm_at<S_LightArea>(lp->m_灯光数据);

			灯光索引[i].m_shadowTexIndex = 阴影纹理.size();
			灯光索引[i].m_matrixIndex = lp->m_灯光阴影矩阵.m_Mem.m_偏移;

			for (uint32 光采样ID = 0; 光采样ID < lp->m_阴影图->count; ++光采样ID) {
				auto* arce = lp->m_阴影图->ptr_userData[光采样ID];

				阴影纹理.push_back(arce);
			}
		}


		f_纹理集_set数量(m_深度阴影纹理集, 阴影纹理.size());
		for (uint32 i = 0; i < 阴影纹理.size(); ++i) {
			f_纹理集_set纹理(m_深度阴影纹理集, 阴影纹理[i], i);
		}
	}
	else {
		
		f_纹理集_set数量(m_深度阴影纹理集, 1);
		f_纹理集_set纹理(m_深度阴影纹理集, f_g_纹理().g_缺损阴影纹理, 0);
		
	}


	if (环境纹理->count) {
		m_全局纹理属性.envTex_num = 0;
		m_全局纹理属性.envTexAtt_Offset = 0;

		f_纹理集_set数量(m_环境纹理集, 环境纹理->count);
		for (uint32 i = 0; i < 环境纹理->count; ++i) {
			f_纹理集_set纹理(m_环境纹理集, 环境纹理->ptr_userData[i], i);
		}
	}
	else {
		m_全局纹理属性.envTex_num = 0;
		m_全局纹理属性.envTexAtt_Offset = 0;

		f_纹理集_set数量(m_环境纹理集, 3);
		f_纹理集_set纹理(m_环境纹理集, S_节点数据::g_缺损环境颜色纹理, 0);
		f_纹理集_set纹理(m_环境纹理集, S_节点数据::g_缺损环境颜色纹理, 1);
		f_纹理集_set纹理(m_环境纹理集, S_节点数据::g_缺损环境颜色纹理, 2);
	}

	f_纹理集_set纹理(m_立方体阴影纹理集, f_g_纹理().g_缺损立方体阴影纹理, 0);



	f_纹理集_set纹理(m_屏幕后期几何纹理集, m_几何缓存渲染层->m_Color[0], DEF_GBuffer_Vert);
	f_纹理集_set纹理(m_屏幕后期几何纹理集, m_几何缓存渲染层->m_Color[1], DEF_GBuffer_Normal);



	//f_NodeCtx_节点模拟入栈(this, false);
	f_异步解算();

	auto& ts = f_prop_纹理集(m_渲染纹理);
	f_纹理集_set纹理(ts.m_纹理集, m_颜色渲染层->m_Color[0], 0);
	return false;
}

void C_光栅渲染节点::f_异步解算() {
	auto* 渲染物体 = DEF_物体插座_1D数据(f_get输入插座(1));
	auto* 摄像机 = DEF_物体插座数据(f_get输入插座(4), 0);
	if (摄像机 && 摄像机->m_Type != E_物体类型::t_摄像机) {
		摄像机 = f_ob_以类型查找子物体(摄像机, E_物体类型::t_摄像机);
	}
	if (!摄像机) return;

	S_摄像机* camera = dynamic_cast<S_摄像机*>(摄像机);

	auto 分辨率 = f_prop_uVec2(m_渲染分辨率);
	auto 图像分块 = (分辨率 / 32) + 1;
	分辨率 = 图像分块 * 32;

	camera->f_set宽高比(_Vec2(分辨率));
	camera->f_Update(nullptr);

	S_Viewport view = { 0, 0, 分辨率.x, 分辨率.y, 0.0f, 1.0f };
	S_Rect2D 裁剪 = { _iVec2(0), 分辨率 };


	S_渲染参数 渲染参数{};



	//m_全局纹理属性.m_ProjMatrix = *(mat4*)&camera->m_相机位置矩阵;
	m_全局纹理属性.m_ProjMatrix = *(mat4*)&camera->m_相机视图投影矩阵;
	m_全局纹理属性.m_cameraLoc = f_camera_get眼睛位置(*camera);
	
	f_buf_fill(f_buf_getGlobal().g_全局纹理属性, &m_全局纹理属性, 1);

	//m_摄像机GPU参数槽.m_参数槽[0] = S_节点数据::g_摄像机矩阵;
	m_摄像机GPU参数槽.m_参数槽[0] = camera->m_投影矩阵;
	m_摄像机GPU参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
	m_摄像机GPU参数槽.m_绑定位置[0] = 0;
	m_摄像机GPU参数槽.m_绑定数量[0] = 1;
	f_df_setGPU参数布局(m_Ctx.m_逻辑设备.设备, m_摄像机GPU参数槽);

	


	m_几何渲染参数槽.m_参数槽[0] = f_buf_getGlobal().g_全局纹理属性;
	m_几何渲染参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
	m_几何渲染参数槽.m_绑定位置[0] = DEF_BindID_GlobalTextAtt;
	m_几何渲染参数槽.m_绑定数量[0] = 1;

	m_几何渲染参数槽.m_参数槽[1] = f_buf_getGlobal().m_灯光索引;
	m_几何渲染参数槽.m_参数类型[1] = E_板载缓存类型::e_SSBO;
	m_几何渲染参数槽.m_绑定位置[1] = DEF_BindID_TexShadow_LightIndex;
	m_几何渲染参数槽.m_绑定数量[1] = 1;

	m_几何渲染参数槽.m_参数槽[2] = f_buf_getGlobal().m_区域光缓冲区;
	m_几何渲染参数槽.m_参数类型[2] = E_板载缓存类型::e_SSBO;
	m_几何渲染参数槽.m_绑定位置[2] = DEF_BindID_TexShadow_AreaLight;
	m_几何渲染参数槽.m_绑定数量[2] = 1;

	m_几何渲染参数槽.m_参数槽[3] = f_buf_getGlobal().g_灯光投影矩阵;
	m_几何渲染参数槽.m_参数类型[3] = E_板载缓存类型::e_SSBO;
	m_几何渲染参数槽.m_绑定位置[3] = DEF_BindID_TexShadow_PVMatrix;
	m_几何渲染参数槽.m_绑定数量[3] = 1;

	f_纹理集_刷新所有纹理信息(m_深度阴影纹理集);
	f_纹理集_刷新所有纹理信息(m_环境纹理集);
	f_纹理集_刷新所有纹理信息(m_立方体阴影纹理集);

	f_纹理槽_设置纹理集(m_几何纹理槽, m_环境纹理集,			0, DEF_BindID_TextureCube);
	f_纹理槽_设置纹理集(m_几何纹理槽, m_深度阴影纹理集,		1, DEF_BindID_TextureShadow);
	f_纹理槽_设置纹理集(m_几何纹理槽, m_立方体阴影纹理集,	2, DEF_BindID_TexCubeShadow);
	

	m_几何渲染参数槽.m_纹理槽 = &m_几何纹理槽;
	f_df_setGPU参数布局(m_Ctx.m_逻辑设备.设备, m_几何渲染参数槽, false);


	//渲染参数.m_视图投影矩阵 = camera->m_投影矩阵;
	渲染参数.m_视口 = &view;
	渲染参数.m_裁剪 = &裁剪;

	f_tex_set纹理颜色附件布局(m_几何缓存渲染层->m_Color[0], 1);
	f_tex_set纹理颜色附件布局(m_几何缓存渲染层->m_Color[1], 1);

	渲染参数.m_线管槽 = E_管线槽::e_几何渲染;
	f_df_BeginDraw(m_几何缓存渲染层->m_Ctx, m_几何缓存渲染层->m_帧缓存, m_几何缓存渲染层->m_交换ID, 3);

	for (uint32 i = 0; i < 渲染物体->count; ++i) {
		auto e = 渲染物体->ptr_userData[i];

		switch (e->m_Type) {
			case E_物体类型::t_物体包:
			case E_物体类型::t_多边形:
			case E_物体类型::t_网格物体: {
				if (!e->m_父对象) f_ob_绘制单个元素(e, 渲染参数, E_物体网格元素类型::e_MT_纹理);
			}
		}
	}

	f_Draw_end_帧缓存(*m_几何缓存渲染层->m_Ctx);




	

	
	f_纹理集_set纹理(m_屏幕后期几何纹理集, m_几何缓存渲染层->m_Color[0], DEF_GBuffer_Vert);
	f_纹理集_set纹理(m_屏幕后期几何纹理集, m_几何缓存渲染层->m_Color[1], DEF_GBuffer_Normal);
	f_纹理集_set纹理(m_屏幕后期阴影纹理集, m_屏幕后期合成纹理, 0);
	
	f_纹理集_刷新所有纹理信息(m_深度阴影纹理集);
	f_纹理集_刷新所有纹理信息(m_屏幕后期几何纹理集);
	f_纹理集_刷新所有纹理信息(m_屏幕后期阴影纹理集);

	f_纹理槽_设置纹理集(m_屏幕后期效果纹理槽, m_深度阴影纹理集, 0, DEF_BindID_TextureShadow);
	f_纹理槽_设置纹理集(m_屏幕后期效果纹理槽, m_屏幕后期几何纹理集, 1, DEF_BindID_GBufferImage);
	f_纹理槽_设置纹理集(m_屏幕后期效果纹理槽, m_屏幕后期阴影纹理集, 2, DEF_BindID_CompositingShadow);
	
	
	m_后期屏幕效果合成参数槽.m_参数槽[0] = f_buf_getGlobal().m_灯光索引;
	m_后期屏幕效果合成参数槽.m_参数类型[0] = E_板载缓存类型::e_SSBO;
	m_后期屏幕效果合成参数槽.m_绑定位置[0] = DEF_BindID_TexShadow_LightIndex;
	m_后期屏幕效果合成参数槽.m_绑定数量[0] = 1;

	m_后期屏幕效果合成参数槽.m_参数槽[1] = f_buf_getGlobal().m_区域光缓冲区;
	m_后期屏幕效果合成参数槽.m_参数类型[1] = E_板载缓存类型::e_SSBO;
	m_后期屏幕效果合成参数槽.m_绑定位置[1] = DEF_BindID_TexShadow_AreaLight;
	m_后期屏幕效果合成参数槽.m_绑定数量[1] = 1;

	m_后期屏幕效果合成参数槽.m_参数槽[2] = f_buf_getGlobal().g_灯光投影矩阵;
	m_后期屏幕效果合成参数槽.m_参数类型[2] = E_板载缓存类型::e_SSBO;
	m_后期屏幕效果合成参数槽.m_绑定位置[2] = DEF_BindID_TexShadow_PVMatrix;
	m_后期屏幕效果合成参数槽.m_绑定数量[2] = 1;

	m_后期屏幕效果合成参数槽.m_纹理槽 = &m_屏幕后期效果纹理槽;

	f_tex_set着色器采样布局(m_几何缓存渲染层->m_Color[0], 1);
	f_tex_set着色器采样布局(m_几何缓存渲染层->m_Color[1], 1);

	//f_df_setGPU参数布局(m_Ctx.m_逻辑设备.设备, m_后期屏幕效果合成参数槽, false);
	f_df_run计算(S_Engine::g_后期处理.g_光栅阴影计算, { 图像分块.x, 图像分块.y, 1 }, m_后期屏幕效果合成参数槽, &m_全局纹理属性);

	


	

	渲染参数.m_线管槽 = E_管线槽::e_颜色渲染;


	f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_环境纹理集, 0, DEF_BindID_TextureCube);
	f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_深度阴影纹理集, 1, DEF_BindID_TextureShadow);
	f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_立方体阴影纹理集, 2, DEF_BindID_TexCubeShadow);
	f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_屏幕后期几何纹理集, 3, DEF_BindID_GBufferImage);
	f_纹理槽_设置纹理集(m_最终渲染纹理槽, m_屏幕后期阴影纹理集, 4, DEF_BindID_CompositingShadow);

	m_最终渲染参数槽.m_参数槽[0] = f_buf_getGlobal().g_全局纹理属性;
	m_最终渲染参数槽.m_参数类型[0] = E_板载缓存类型::e_UBO;
	m_最终渲染参数槽.m_绑定位置[0] = DEF_BindID_GlobalTextAtt;
	m_最终渲染参数槽.m_绑定数量[0] = 1;

	m_最终渲染参数槽.m_参数槽[1] = f_buf_getGlobal().m_灯光索引;
	m_最终渲染参数槽.m_参数类型[1] = E_板载缓存类型::e_SSBO;
	m_最终渲染参数槽.m_绑定位置[1] = DEF_BindID_TexShadow_LightIndex;
	m_最终渲染参数槽.m_绑定数量[1] = 1;

	m_最终渲染参数槽.m_参数槽[2] = f_buf_getGlobal().m_区域光缓冲区;
	m_最终渲染参数槽.m_参数类型[2] = E_板载缓存类型::e_SSBO;
	m_最终渲染参数槽.m_绑定位置[2] = DEF_BindID_TexShadow_AreaLight;
	m_最终渲染参数槽.m_绑定数量[2] = 1;

	m_最终渲染参数槽.m_参数槽[3] = f_buf_getGlobal().g_灯光投影矩阵;
	m_最终渲染参数槽.m_参数类型[3] = E_板载缓存类型::e_SSBO;
	m_最终渲染参数槽.m_绑定位置[3] = DEF_BindID_TexShadow_PVMatrix;
	m_最终渲染参数槽.m_绑定数量[3] = 1;

	m_最终渲染参数槽.m_参数槽[4] = f_buf_getGlobal().g_材质;
	m_最终渲染参数槽.m_参数类型[4] = E_板载缓存类型::e_SSBO;
	m_最终渲染参数槽.m_绑定位置[4] = DEF_BINDING_TasterBindID_MaterialID;
	m_最终渲染参数槽.m_绑定数量[4] = 1;

	m_最终渲染参数槽.m_纹理槽 = &m_最终渲染纹理槽;

	f_df_setGPU参数布局(m_Ctx.m_逻辑设备.设备, m_最终渲染参数槽, false);
	f_df_BeginDraw(m_颜色渲染层->m_Ctx, m_颜色渲染层->m_帧缓存, m_颜色渲染层->m_交换ID, 3);

	for (uint32 i = 0; i < 渲染物体->count; ++i) {
		auto e = 渲染物体->ptr_userData[i];

		switch (e->m_Type) {
			case E_物体类型::t_物体包:
			case E_物体类型::t_多边形:
			case E_物体类型::t_网格物体: {
				if (!e->m_父对象) f_ob_绘制单个元素(e, 渲染参数, E_物体网格元素类型::e_MT_纹理);
			}
		}
	}

	f_Draw_end_帧缓存(*m_颜色渲染层->m_Ctx);

	
}

void C_光栅渲染节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_5, S_引擎配置::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_渲染分辨率, 下一次读取数据指针);

			下一次读取数据指针 = f_prop_Load(m_AO深度偏移, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_AO半径, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_AO强度, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_AO厚度, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_AO采样, 下一次读取数据指针);

			下一次读取数据指针 = f_prop_Load(m_阴影强度, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_阴影采样, 下一次读取数据指针);

			下一次读取数据指针 = f_prop_Load(m_环境亮度, 下一次读取数据指针);
			//下一次读取数据指针 = f_ob_Load物体(m_Ob, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_光栅渲染节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_渲染分辨率, 块);

	f_prop_Save(m_AO深度偏移, 块);
	f_prop_Save(m_AO半径, 块);
	f_prop_Save(m_AO强度, 块);
	f_prop_Save(m_AO厚度, 块);
	f_prop_Save(m_AO采样, 块);

	f_prop_Save(m_阴影强度, 块);
	f_prop_Save(m_阴影采样, 块);

	f_prop_Save(m_环境亮度, 块);
	//f_ob_Save物体(m_Ob, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建光栅渲染节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_光栅渲染节点(ctx);
}

C_节点基类* f_node_加载光栅渲染节点(S_设备环境& ctx, FILE* f) {
	C_光栅渲染节点* node = new C_光栅渲染节点(ctx);
	return node;
}

void f_node_保存光栅渲染节点(C_节点基类* n, FILE* f) {
	C_光栅渲染节点* node = dynamic_cast<C_光栅渲染节点*>(n);
}








